# coding=utf-8
"""
https://stackoverflow.com/questions/56059694/signal-handler-must-be-signal-sig-ign-signal-sig-dfl-or-a-callable-object
"""
import os
import time
# async
import signal
import asyncio
import subprocess

from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor


# 运行阻塞任务
"""
参考 sync_cmd_async_run.py
"""


def sync_cmd(cmd=None):
    if cmd is None:
        cmd = "ping -c 10 www.baidu.com"
    p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    out, err = p.communicate(timeout=5)
    return out, err


def test_sync():
    tasks = [sync_cmd() for i in range(5)]
    for d in tasks:
        print(d)


# 异步任务
def signal_handler(signal, frame):
    loop.stop()
    # client.close()
    print(signal, frame)
    sys.exit(0)


async def async_cmd(cmd=None, loop=None, timeout=5):
    if cmd is None:
        cmd = "ping -c 10 www.baidu.com"
    p = await asyncio.create_subprocess_shell(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                                              stderr=subprocess.PIPE, loop=loop)
    try:
        fut = await asyncio.wait_for(p.communicate(), timeout=timeout)
        return p.returncode, fut
    except asyncio.TimeoutError:
        p.kill()
        return p.returncode, None


async def tasks_async(loop=None):
    tasks = [async_cmd(loop=loop) for i in range(5)]
    data = await asyncio.gather(*tasks)
    for d in data:
        print(d)


def test_async():
    t1 = time.time()
    try:
        loop = asyncio.get_event_loop()
        # signal.signal(signal.SIGINT, signal_handler)
        # loop.add_signal_handler(15, signal_handler)

        exitcode = loop.run_until_complete(async_cmd(loop=loop))
        # exitcode = loop.run_until_complete(tasks_async(loop=loop))
        loop.close()
    except Exception as e:
        print(e)
        exitcode = 1
    print("{} used:", exitcode, time.time() - t1)


if __name__ == '__main__':
    t1 = time.time()
    test_async()
    print(time.time() - t1)


